package com.javabasic.serialize.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;

/**
 * @author mir.xiong
 * @version 1.0
 * @description
 * @link
 *  - [Jackson(1)之ObjectMapper配置详解](https://blog.csdn.net/Seky_fei/article/details/109960178)
 *  - [Jackson使用详解](https://juejin.cn/post/6844904166809157639)
 *  - [jackson 实体转json 为NULL或者为空不参加序列化](https://blog.csdn.net/liuxiao723846/article/details/46043933)
 *  - [Spring Boot:自定义Jackson ObjectMapper](https://blog.csdn.net/niugang0920/article/details/115748241)
 * @since Created by work on 2021/11/28 4:36 下午
 */
public class SerializeUtils {

    public volatile static ObjectMapper objectMapper;

    public static ObjectMapper getObjectMapper() {
        if (objectMapper == null) {
            synchronized (SerializeUtils.class) {
                if (objectMapper == null) {
                    objectMapper = new ObjectMapper()
                            // 配置ObjectMapper忽略json字符串中多余的未知属性
                            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                            // 默认情况下ObjectMapper序列化没有属性的空对象时会抛异常。可以通过SerializationFeature.FAIL_ON_EMPTY_BEANS设置当对象没有属性时，让其序列化能成功，不抛异常。
                            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false)
                            // Jackson对时间(Date)序列化的转换格式默认是时间戳，可以取消时间的默认时间戳转化格式；默认时间戳转化格式取消后在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ，同时需要设置要展现的时间格式。
                            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
                            // 当json字符串里带注释符时，默认情况下解析器不能解析。Feature.ALLOW_COMMENTS特性决定解析器是否允许解析使用Java/C++ 样式的注释（包括'/'+'*' 和'//' 变量）
                            .configure(JsonParser.Feature.ALLOW_COMMENTS, true)
                            // 取消Jackson时间的默认时间戳转化格式，并设置需要展现的时间格式
                            .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
                            // Include.Include.ALWAYS 默认 均序列化
                            // Include.NON_DEFAULT 属性为默认值不序列化
                            // Include.NON_EMPTY 属性为 空（""） 或者为 NULL 都不序列化
                            // Include.NON_NULL 属性为NULL 不序列化
                            .setSerializationInclusion(JsonInclude.Include.ALWAYS)
                            ;
                }
            }
        }
        return objectMapper;
    }
}
